package demoMod.moduploader.ui;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import demoMod.gdxform.abstracts.Container;
import demoMod.gdxform.core.FormManager;
import demoMod.gdxform.helpers.FontHelper;
import demoMod.gdxform.interfaces.Element;
import demoMod.gdxform.interfaces.MouseEventSubscriber;
import demoMod.gdxform.ui.*;
import demoMod.moduploader.core.MainWindow;
import demoMod.moduploader.fonts.FontKeys;
import demoMod.moduploader.interfaces.Refreshable;
import demoMod.moduploader.interfaces.ReloadStringsSubscriber;
import demoMod.moduploader.localization.LocalizedStrings;
import demoMod.moduploader.model.ModUploadItem;

import java.io.File;
import java.util.*;

public class ModListPane extends Container<Element> implements MouseEventSubscriber, ReloadStringsSubscriber, Refreshable {
    public static final String ID = "ModListPane";
    private final GScrollPane scrollPane;
    private final ModList modList = new ModList();
    private static List<String> strings;
    private boolean mouseDown = false;

    public ModListPane() {
        if (strings == null) {
            strings = LocalizedStrings.getStrings(ID);
        }
        float len = Math.min(Gdx.graphics.getWidth() * 0.8F, Gdx.graphics.getHeight() * 0.9F);
        setX((Gdx.graphics.getWidth() - len) / 2.0F);
        setY(0);
        setWidth(len);
        setHeight(len);
        setId(ID);
        setBackground(Color.WHITE.cpy());
        setBackground(MainWindow.steamBgColor.cpy());
        scrollPane = new GScrollPane(0, 0, getWidth(), getHeight(), getWidth(), getHeight()) {
            @Override
            public float getWidth() {
                return ModListPane.this.getWidth();
            }
        };
        scrollPane.setBackground(Color.WHITE.cpy());
        scrollPane.setBackground(MainWindow.steamBgColor.cpy());
        GVScrollBar vScrollBar = new GVScrollBar(0, 0, 10, getHeight());
        scrollPane.setVScrollBar(vScrollBar);
        addElement(scrollPane);
        modList.setCellHeight(len / 3.0F);
        modList.setCellWidth(len / 3.0F);
        scrollPane.addElement(modList);
        LocalizedStrings.subscribe(this);
    }

    public GScrollPane getScrollPane() {
        return scrollPane;
    }

    public ModList getModList() {
        return modList;
    }

    public void addModItem(ModUploadItem uploadItem) {
        ModDisplayItem modDisplayItem = new ModDisplayItem(FontHelper.getFont(FontKeys.SIM_HEI_16), uploadItem);
        modList.addItem(modDisplayItem);
        modDisplayItem.setId(UUID.randomUUID().toString());
        if (modList.getHeight() > scrollPane.getPlainHeight()) {
            scrollPane.setPlainHeight(modList.getHeight());
        }
    }

    public void clear() {
        for (Element element : modList.getElements()) {
            element.dispose();
        }
        modList.clear();
        scrollPane.setPlainHeight(getHeight());
    }

    @Override
    public boolean clickDown(int screenX, int screenY, int button) {
        if (screenX > getX(true) && screenX < getX(true) + getWidth() && Gdx.graphics.getHeight() - screenY > getY(true)
                && Gdx.graphics.getHeight() - screenY < getY(true) + getHeight()) {
            mouseDown = true;
            FormManager.getInstance().moveToTop(this);
            List<Element> elements = this.getElements();
            for(int i = elements.size() - 1; i >= 0; --i) {
                Element element = elements.get(i);
                if (element instanceof MouseEventSubscriber && ((MouseEventSubscriber)element).clickDown(screenX, screenY, button)) {
                    return true;
                }
            }
            FormManager.getInstance().getEventHooks().setCurrentFocusedElement(this);
            return true;
        }
        return false;
    }

    @Override
    public boolean clickUp(int screenX, int screenY, int button) {
        if (!this.mouseDown) return false;
        this.mouseDown = false;
        List<Element> elements = this.getElements();

        for(int i = elements.size() - 1; i >= 0; --i) {
            Element element = elements.get(i);
            if (element instanceof MouseEventSubscriber && ((MouseEventSubscriber)element).clickUp(screenX, screenY, button)) {
                break;
            }
        }
        return true;
    }

    @Override
    public boolean mouseDragged(int screenX, int screenY) {
        List<Element> elements = getElements();
        for (int i=elements.size() - 1;i >= 0;i--) {
            Element element = elements.get(i);
            if (element instanceof MouseEventSubscriber) {
                if (((MouseEventSubscriber) element).mouseDragged(screenX, screenY)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean mouseMoved(int i, int i1) {
        return false;
    }

    @Override
    public boolean scrolled(int amount) {
        if (!this.visible()) return false;
        List<Element> elements = getElements();
        for (int i=elements.size() - 1;i >= 0;i--) {
            Element element = elements.get(i);
            if (element instanceof MouseEventSubscriber) {
                if (((MouseEventSubscriber) element).scrolled(amount)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean moveToElementBorder(Element element) {
        return false;
    }

    @Override
    public void onReloadStrings() {

    }

    @Override
    public boolean hasFocus() {
        return true;
    }

    @Override
    public void refresh() {
        if (MainWindow.inst.getModCollectionPath() == null) {
            return;
        }
        clear();
        File[] folders = new File(MainWindow.inst.getModCollectionPath()).listFiles(File::isDirectory);
        if (folders != null) {
            for (File dir : folders) {
                File configFile = new File(dir, "config.json");
                File modImage = new File(dir, "image.jpg");
                File contentFolder = new File(dir, "content");
                ModUploadItem uploadItem = new ModUploadItem();
                uploadItem.setModConfigFile(configFile);
                uploadItem.setModImage(modImage);
                uploadItem.setModContentFolder(contentFolder);
                if (uploadItem.generateModInfo() == null) {
                    continue;
                }
                if (!modImage.exists() || !modImage.isFile()) {
                    continue;
                }
                if (!contentFolder.exists() || !contentFolder.isDirectory()) {
                    continue;
                }
                addModItem(uploadItem);
            }
        }
    }
}
